#include "rs485_frame_assemble.h"
#include "device_resource.h"
#include "modbus_rtu_comm.h"
#include "rs485_comm_analyse.h"
uint16_t get_begin_register_addrss(uint8_t order_type)
{
  switch (order_type)
  {
  case CONTROL_CMD:             // = 0x00,                 ///< 控制命令
  case OVP_ENABLE:              // = 0x01,              ///< 过压保护使能
  case OVP_THRESHOLD:           // = 0x02,           ///< 过压保护阈值
  case OCP_ENABLE:              // = 0x03,              ///< 过流保护使能
  case OCP_THRESHOLD_RATED:     // = 0x04,     ///< 过流保护阈值（额定电流）
  case OVP_DELAY_TIME:          // = 0x05,          ///< 过压保护延时时间
  case OCP_DELAY_TIME_DEFINITE: // = 0x06, ///< 过流保护延时时间（定时限）
  case UVLO_ENABLE:             // = 0x07,             ///< 欠压保护使能
  case UVLO_THRESHOLD:          // = 0x08,          ///< 欠压保护阈值
  case UVLO_DELAY_TIME:         // = 0x09,         ///< 欠压保护延时时间
    return 0x3000 + order_type - CONTROL_CMD;
  // 预留区间（0x0A~0x15，共12个位置）
  case RESERVED_0A_TO_15: // = 0x0A, ///< 预留（0x0A~0x15）
    return 0xFFFF;
    // 端口过温保护（0x16~0x18）
  case PORT_OTP_ENABLE:     // = 0x16,         ///< 端口过温保护使能
  case PORT_OTP_THRESHOLD:  // = 0x17,  ///< 端口过温保护阈值
  case PORT_OTP_DELAY_TIME: // = 0x18, ///< 端口过温保护延时时间
    return 0x3016 + order_type - PORT_OTP_ENABLE;
    // 预留区间（0x19~0x1B，共3个位置）
  case RESERVED_19_TO_1B: // = 0x19, ///< 预留（0x19~0x1B）
    return 0xFFFF;
  // 板载过温保护（0x1C~0x1E）
  case BOARD_OTP_ENABLE:     // = 0x1C,     ///< 板载过温保护使能
  case BOARD_OTP_THRESHOLD:  // = 0x1D,  ///< 板载过温保护阈值
  case BOARD_OTP_DELAY_TIME: // = 0x1E, ///< 板载过温保护延时时间
    return 0x301C + order_type - BOARD_OTP_ENABLE;
  // 预留区间（0x1F~0x2D，共15个位置）
  case RESERVED_1F_TO_2D: // = 0x1F, ///< 预留（0x1F~0x2D）
    return 0xFFFF;
  // 恢复与报警配置（0x2E~0x36）
  case OVP_AUTO_RECOVER_ENABLE:     // = 0x2E,     ///< 过压自恢复使能
  case UVLO_AUTO_RECOVER_ENABLE:    // = 0x2F,    ///< 欠压自恢复使能
  case VOLTAGE_RECOVERY_HYSTERESIS: // = 0x30, ///< 电压恢复回差值
  case OCP_AUTO_RECLOSE_ENABLE:     // = 0x31,     ///< 过流自动重合使能
  case OCP_AUTO_RECLOSE_DELAY:      // = 0x32,      ///< 过流自动重合延时时间
  case OCP_AUTO_RECLOSE_COUNT:      // = 0x33,      ///< 过流自动重合次数
  case OCP_ALARM_THRESHOLD:         // = 0x34,         ///< 过流报警阈值
  case USER_CODE:                   // = 0x35,                   ///< 用户代码
  case AIR_SWITCH_TRIP_ALARM_MODE:  // = 0x36,  ///< 空开断开告警方式
    return 0x302E + order_type - OVP_AUTO_RECOVER_ENABLE;
  case REQUEST_STATUS_1800_181B:
    return 0x1800;
  case REQUEST_STATUS_1824_1828:
    return 0x1824;
  case REQUEST_STATUS_18A4_18B5:
    return 0x18A4;
  case REQUEST_STATUS_1900_190E:
    return 0x1900;
  case REQUEST_STATUS_3000_3009:
    return 0x3000;
  case REQUEST_STATUS_3016_301E:
    return 0x3016;
  case REQUEST_STATUS_302E_3036:
    return 0x302E;
  default:
    return 0xFFFF;
  }
}
uint16_t get_request_registet_count(uint8_t order_type)
{
  switch (order_type) // 修正原函数中可能的笔误，使用参数order_type而非cro_st->order_type
  {
  case REQUEST_STATUS_1800_181B:
    return 0x181B - 0x1800 + 1; // 0x1C (28个寄存器)
  case REQUEST_STATUS_1824_1828:
    return 0x1828 - 0x1824 + 1; // 0x05 (5个寄存器)
  case REQUEST_STATUS_18A4_18B5:
    return 0x18B5 - 0x18A4 + 1; // 0x12 (18个寄存器)
  case REQUEST_STATUS_1900_190E:
    return 0x190E - 0x1900 + 1; // 0x0F (15个寄存器)
  case REQUEST_STATUS_3000_3009:
    return 0x3009 - 0x3000 + 1; // 0x0A (10个寄存器)
  case REQUEST_STATUS_3016_301E:
    return 0x301E - 0x3016 + 1; // 0x09 (9个寄存器)
  case REQUEST_STATUS_302E_3036:
    return 0x3036 - 0x302E + 1; // 0x09 (9个寄存器)
  default:
    return 0; // 默认与REQUEST_STATUS_1800_181B保持一致，返回28个
  }
}
int assemble_ctrl_request_relay_unit_frame(CTRL_REQ_ORDER_STRUCT *cro_st,
                                           uint8_t *send_data,
                                           uint16_t *send_lenth)
{
  uint16_t begen_register_addrss, reqest_registet_count, register_data;
  uint8_t ctrl_unit_box;
  ctrl_unit_box = get_box_from_bound_index(cro_st->ctrl_unit_index);
  if (ctrl_unit_box == 0)
  {
    return -1;
  }
  begen_register_addrss = get_begin_register_addrss(cro_st->order_type);
  if (begen_register_addrss == 0xFFFF)
  {
    return -1;
  }
  switch (cro_st->order_type)
  {
  case CONTROL_CMD:             // = 0x00,                 ///< 控制命令
  case OVP_ENABLE:              // = 0x01,              ///< 过压保护使能
  case OVP_THRESHOLD:           // = 0x02,           ///< 过压保护阈值
  case OCP_ENABLE:              // = 0x03,              ///< 过流保护使能
  case OCP_THRESHOLD_RATED:     // = 0x04,     ///< 过流保护阈值（额定电流）
  case OVP_DELAY_TIME:          // = 0x05,          ///< 过压保护延时时间
  case OCP_DELAY_TIME_DEFINITE: // = 0x06, ///< 过流保护延时时间（定时限）
  case UVLO_ENABLE:             // = 0x07,             ///< 欠压保护使能
  case UVLO_THRESHOLD:          // = 0x08,          ///< 欠压保护阈值
  case UVLO_DELAY_TIME:         // = 0x09,         ///< 欠压保护延时时间
  // 预留区间（0x0A~0x15，共12个位置）
  case RESERVED_0A_TO_15:   // = 0x0A, ///< 预留（0x0A~0x15）
                            // 端口过温保护（0x16~0x18）
  case PORT_OTP_ENABLE:     // = 0x16,         ///< 端口过温保护使能
  case PORT_OTP_THRESHOLD:  // = 0x17,  ///< 端口过温保护阈值
  case PORT_OTP_DELAY_TIME: // = 0x18, ///< 端口过温保护延时时间
                            // 预留区间（0x19~0x1B，共3个位置）
  case RESERVED_19_TO_1B:   // = 0x19, ///< 预留（0x19~0x1B）
  // 板载过温保护（0x1C~0x1E）
  case BOARD_OTP_ENABLE:     // = 0x1C,     ///< 板载过温保护使能
  case BOARD_OTP_THRESHOLD:  // = 0x1D,  ///< 板载过温保护阈值
  case BOARD_OTP_DELAY_TIME: // = 0x1E, ///< 板载过温保护延时时间
  // 预留区间（0x1F~0x2D，共15个位置）
  case RESERVED_1F_TO_2D: // = 0x1F, ///< 预留（0x1F~0x2D）
  // 恢复与报警配置（0x2E~0x36）
  case OVP_AUTO_RECOVER_ENABLE:     // = 0x2E,     ///< 过压自恢复使能
  case UVLO_AUTO_RECOVER_ENABLE:    // = 0x2F,    ///< 欠压自恢复使能
  case VOLTAGE_RECOVERY_HYSTERESIS: // = 0x30, ///< 电压恢复回差值
  case OCP_AUTO_RECLOSE_ENABLE:     // = 0x31,     ///< 过流自动重合使能
  case OCP_AUTO_RECLOSE_DELAY:      // = 0x32,      ///< 过流自动重合延时时间
  case OCP_AUTO_RECLOSE_COUNT:      // = 0x33,      ///< 过流自动重合次数
  case OCP_ALARM_THRESHOLD:         // = 0x34,         ///< 过流报警阈值
  case USER_CODE:                   // = 0x35,                   ///< 用户代码
  case AIR_SWITCH_TRIP_ALARM_MODE:  // = 0x36,  ///< 空开断开告警方式
    register_data = cro_st->order_data;
    return assemble_ctrl_relay_unit_frame(ctrl_unit_box,
                                          begen_register_addrss,
                                          register_data, send_data,
                                          send_lenth);
  case REQUEST_STATUS_1800_181B: ///< 请求状态（固定值0xff）
  case REQUEST_STATUS_1824_1828:
  case REQUEST_STATUS_18A4_18B5:
  case REQUEST_STATUS_1900_190E:
  case REQUEST_STATUS_3000_3009:
  case REQUEST_STATUS_3016_301E:
  case REQUEST_STATUS_302E_3036:
    reqest_registet_count = get_request_registet_count(cro_st->order_type);
    if (reqest_registet_count == 0)
    {
      return -1;
    }
    return assemble_request_relay_unit_frame(ctrl_unit_box,
                                             begen_register_addrss,
                                             reqest_registet_count,
                                             send_data,
                                             send_lenth);
  default:
    return -1;
  }
}

int assemble_request_relay_unit_frame(uint8_t box, uint16_t begin_register_addrss, uint16_t reqest_registet_count, uint8_t *send_data, uint16_t *send_lenth)
{
  uint16_t crc16;
  send_data[0] = box;
  send_data[1] = 0x03;
  send_data[2] = HI_UINT16(begin_register_addrss);
  send_data[3] = LO_UINT16(begin_register_addrss);
  send_data[4] = HI_UINT16(reqest_registet_count);
  send_data[5] = LO_UINT16(reqest_registet_count);
  crc16 = usMBCRC16(send_data, 6);
  send_data[6] = LO_UINT16(crc16);
  send_data[7] = HI_UINT16(crc16);
  *send_lenth = 8;
  return 0;
}
int assemble_ctrl_relay_unit_frame(uint8_t box, uint16_t begin_reg_addr, uint16_t reg_value, uint8_t *send_data, uint16_t *send_lenth)
{
  uint16_t crc16;
  send_data[0] = box;
  send_data[1] = 0x10;
  send_data[2] = HI_UINT16(begin_reg_addr);
  send_data[3] = LO_UINT16(begin_reg_addr);
  send_data[4] = 00;
  send_data[5] = 01;
  send_data[6] = 0x02;
  send_data[7] = HI_UINT16(reg_value);
  send_data[8] = LO_UINT16(reg_value);
  crc16 = usMBCRC16(send_data, 9);
  send_data[9] = LO_UINT16(crc16);
  send_data[10] = HI_UINT16(crc16);
  *send_lenth = 11;
  return 0;
}
